#include "StdAfx.h"
#include "AppInvoker.h"

#define BUFSIZE 4096

CAppInvoker::CAppInvoker(void)
:m_hChildStdIn(NULL)
,m_hChildStdOut(NULL)
,m_hChildStdErr(NULL)
{
}

CAppInvoker::~CAppInvoker(void)
{
}

bool CAppInvoker::Invoke(LPCTSTR path, LPCTSTR param, bool bStdIn, bool bStdOut, bool bStdError)
{
    TCHAR* pCmd = new TCHAR[_tcslen(param) + 1];
    HANDLE hRead,hWrite;
    SECURITY_ATTRIBUTES saAttr; 
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;


    STARTUPINFO si = { sizeof(si) };
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESTDHANDLES;
    if(bStdOut){
        if(::CreatePipe(&hRead,&hWrite,&saAttr,BUFSIZE)){
            si.hStdOutput = hWrite;
            m_hChildStdOut = hRead;
            DWORD id;
            HANDLE hThread = ::CreateThread(NULL,0,StdOutProc,this,0,&id);
            ::CloseHandle(hThread);
        }
    }

    if(bStdError){
        if(::CreatePipe(&hRead,&hWrite,&saAttr,BUFSIZE)){
            si.hStdError = hWrite;
            m_hChildStdErr = hRead;
        }
    }

    if(bStdIn){
        if(::CreatePipe(&hRead,&hWrite,&saAttr,BUFSIZE)){
            si.hStdInput = hRead;
            m_hChildStdIn = hWrite;
        }
    }

    PROCESS_INFORMATION pi;
    _tcscpy(pCmd,param);
    BOOL res = ::CreateProcess(path,pCmd,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
    DWORD err = GetLastError();
    delete [] pCmd;
    return res == FALSE ? false : true;
}

DWORD WINAPI CAppInvoker::StdOutProc(LPVOID pVoid)
{
    return ((CAppInvoker*)(pVoid))->StdOutProc();
}

void OnStdOutData2(void* buf, size_t len)
{
    TCHAR* str = new TCHAR[len + 1];
    memset(str,0,len+1);
    memcpy(str,buf,len);
    AfxMessageBox(str);
}

DWORD CAppInvoker::StdOutProc(void)
{
    BYTE buf[BUFSIZE+100];
    DWORD dwRead;
    BOOL fSuccess;
    while(true){
        fSuccess = ReadFile(m_hChildStdOut,buf, BUFSIZE, &dwRead, NULL);
        if (! fSuccess || dwRead == 0) 
            break;
        OnStdOutData(buf,dwRead);
    }
    return 0;
}
/*
void CAppInvoker::OnStdOutData(void* buf, size_t len)
{
    TCHAR* str = new TCHAR[len + 2];
    memset(str,0,len+2);
    memcpy(str,buf,len);
    AfxMessageBox(str);
}
*/
